"""
亚平科技平台API客户端
"""
import json
import base64
import requests
from typing import Dict, Any, Optional
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad


class YaPingError(Exception):
    """亚平API基础异常类"""
    pass


class ConfigError(Exception):
    """配置错误"""
    pass


class APIError(Exception):
    """API错误"""
    def __init__(self, code, message):
        self.code = code
        self.message = message
        super().__init__(f"{code}: {message}")


class ValidationError(Exception):
    """验证错误"""
    pass


class YaPingClient:
    """亚平科技平台API客户端"""
    
    def __init__(self, app_id: str, app_secret: str, base_url: str = "https://mp-api.66-six.com"):
        """
        初始化客户端
        
        Args:
            app_id: 平台分配的APP_ID
            app_secret: 平台分配的APP_SECRET
            base_url: API基础URL，默认为正式环境
        """
        if not app_id or not app_secret:
            raise ConfigError("APP_ID和APP_SECRET不能为空")
            
        self.app_id = app_id
        # 截取前32字节作为AES密钥
        self.key = app_secret[:32].encode('utf-8')
        self.base_url = base_url.rstrip('/')  # 移除末尾的斜杠
        
    def encrypt(self, string: str) -> str:
        """
        使用AES-256-ECB加密数据
        
        Args:
            string: 要加密的字符串
            
        Returns:
            加密后的base64字符串
        """
        cipher = AES.new(self.key, AES.MODE_ECB)
        # 使用 pad 函数自动进行 PKCS7 填充
        padded_string = pad(string.encode('utf-8'), AES.block_size)
        data = cipher.encrypt(padded_string)
        return base64.b64encode(data).decode('utf-8')
        
    def _make_request(self, endpoint: str, data: dict = None) -> dict:
        """
        发送API请求
        
        Args:
            endpoint: API端点
            data: 请求数据
            
        Returns:
            解密后的响应数据
        """
        url = f"{self.base_url}{endpoint}"
        
        # 准备请求数据
        if data is None:
            data = {}
            
        # 加密数据
        json_str = json.dumps(data)
        encrypted_data = self.encrypt(json_str)
        
        # 构建最终请求
        request_data = {
            "app_id": self.app_id,
            "json_data": encrypted_data
        }
        
        try:
            response = requests.post(url, json=request_data)
            response_data = response.json()
            
            if not response_data.get("success"):
                raise APIError(
                    code=response_data.get("code"),
                    message=response_data.get("message", "未知错误")
                )
                        
            return response_data.get("data", response_data)
            
        except requests.exceptions.RequestException as e:
            raise APIError(
                code=500,
                message=f"请求失败: {str(e)}"
            )
            
    def verify_callback(self, data: str) -> bool:
        """
        验证回调消息
        
        Args:
            data: 回调消息数据
            
        Returns:
            验证是否成功
        """
        try:
            decrypted_data = self.decrypt(data)
            return True
        except Exception:
            return False
            
    def validate_callback_url(self, callback_url: str) -> bool:
        """
        验证回调URL是否有效
        
        Args:
            callback_url: 回调URL
            
        Returns:
            URL是否有效
        """
        if not callback_url.startswith(("http://", "https://")):
            raise ValidationError("回调URL必须以http://或https://开头")
        return True

    def get_card(self, goods_id: int) -> dict:
        """
        商品选号接口
        
        Args:
            goods_id: 商品ID
            
        Returns:
            选号结果数据
        """
        request_data = {
            "goods_id": goods_id
        }
        
        return self._make_request(
            endpoint="/open/api/get_card",
            data=request_data
        )

    def list_order(self, order_sn: str = None, page: int = 1, page_size: int = 10) -> dict:
        """
        查询订单列表
        
        Args:
            order_sn: 订单号，多个订单号用英文逗号分隔
            page: 页码，默认1
            page_size: 每页数量，默认20
            
        Returns:
            订单列表数据
        """
        data = {
            "page": page,
            "page_size": page_size
        }
        
        if order_sn:
            data["order_sn"] = order_sn
            
        return self._make_request("/open/api/list_order", data)

    def push_order(self,
                   goods_id: int,
                   select_mobile: str,
                   name: str,
                   card: str,
                   mobile: str,
                   province_code: str,
                   province: str,
                   city_code: str,
                   city: str,
                   district_code: str,
                   district: str,
                   address: str,
                   order_sn: str = None,
                   timestamp: str = None,
                   check_code: str = None,
                   select_city: str = None,
                   front_card: str = None,
                   back_card: str = None,
                   face_card: str = None) -> dict:
        """
        提交订单接口
        
        Args:
            goods_id: 商品ID
            select_mobile: 选择的号码
            name: 姓名（必须是中文）
            card: 身份证号码
            mobile: 联系手机号
            province_code: 省份编码
            province: 省份
            city_code: 城市编码
            city: 城市
            district_code: 区县编码
            district: 区县
            address: 详细地址
            order_sn: 订单号，可选
            timestamp: 时间戳，可选
            check_code: 校验码，可选
            select_city: 选择的城市，可选
            front_card: 身份证正面照片URL，可选
            back_card: 身份证背面照片URL，可选
            face_card: 身份证人像照片URL，可选
            
        Returns:
            订单提交结果
        """
        # 构建请求数据
        request_data = {
            "goods_id": goods_id,
            "select_mobile": select_mobile,
            "name": name,
            "card": card,
            "mobile": mobile,
            "province_code": province_code,
            "province": province,
            "city_code": city_code,
            "city": city,
            "district_code": district_code,
            "district": district,
            "address": address
        }
        
        # 添加可选参数
        if order_sn:
            request_data["order_sn"] = order_sn
        if timestamp:
            request_data["timestamp"] = timestamp
        if check_code:
            request_data["check_code"] = check_code
        if select_city:
            request_data["select_city"] = select_city
        if front_card:
            request_data["front_card"] = front_card
        if back_card:
            request_data["back_card"] = back_card
        if face_card:
            request_data["face_card"] = face_card
        
        # 发送请求
        return self._make_request(
            endpoint="/open/api/push_order",
            data=request_data
        )
